//
//  ReservationConfig.swift
//  CMB250716
//
//  Created by Assistant on 2025-01-02.
//

import Foundation

/// 预订配置
struct ReservationConfig {
    
    // MARK: - 基础配置
    
    /// 最小预订人数
    static let minimumPartySize = 1
    
    /// 最大预订人数
    static let maximumPartySize = 20
    
    /// 时间间隔（分钟）
    static let timeIntervalMinutes = 10
    
    /// 预订超时时间（分钟）
    static let reservationTimeoutMinutes = 40
    
    /// 是否需要全款支付
    static let requiresFullPayment = true
    
    /// 是否允许退款
    static let allowsRefund = false
    
    // MARK: - 业务逻辑配置
    struct BusinessLogic {
        /// 时间段间隔（分钟）
        static let timeSlotInterval = 10
        
        /// 最大显示时间段数量
        static let maxTimeSlots = 60
        
        /// 默认预订时长（分钟）
        static let defaultReservationDuration = 90
        
        /// 翻台时间（分钟）- 每个预订单位的用餐时间
        static let turnoverTime = 40
    }
    
    // MARK: - 座位配置
    
    /// 室内座位配置
    struct IndoorSeating {
        /// 室内桌子数量
        static let tableCount = 19
        
        /// 每桌座位数
        static let seatsPerTable = 2
        
        /// 总座位数
        static var totalSeats: Int {
            return tableCount * seatsPerTable // 38 seats
        }
    }
    
    /// 户外座位配置
    struct OutdoorSeating {
        /// 户外桌子数量
        static let tableCount = 15
        
        /// 每桌座位数
        static let seatsPerTable = 2
        
        /// 总座位数
        static var totalSeats: Int {
            return tableCount * seatsPerTable // 30 seats
        }
    }
    
    // MARK: - 座位类型
    
    /// 座位类型枚举
    enum SeatingType: String, CaseIterable, Identifiable, Codable {
        case indoor = "indoor"
        case outdoor = "outdoor"
        
        var id: String { rawValue }
        
        /// 中文名称
        var chineseName: String {
            switch self {
            case .indoor:
                return "室内座位"
            case .outdoor:
                return "户外座位"
            }
        }
        
        /// 英文名称
        var englishName: String {
            switch self {
            case .indoor:
                return "Indoor"
            case .outdoor:
                return "Outdoor"
            }
        }
        
        /// 获取可用桌子数量
        var availableTableCount: Int {
            switch self {
            case .indoor:
                return IndoorSeating.tableCount
            case .outdoor:
                return OutdoorSeating.tableCount
            }
        }
        
        /// 获取每桌座位数
        var seatsPerTable: Int {
            switch self {
            case .indoor:
                return IndoorSeating.seatsPerTable
            case .outdoor:
                return OutdoorSeating.seatsPerTable
            }
        }
        
        /// 获取总座位数
        var totalSeats: Int {
            switch self {
            case .indoor:
                return IndoorSeating.totalSeats
            case .outdoor:
                return OutdoorSeating.totalSeats
            }
        }
        
        /// 图标名称
        var iconName: String {
            switch self {
            case .indoor:
                return "house.fill"
            case .outdoor:
                return "tree.fill"
            }
        }
        
        /// 描述
        var chineseDescription: String {
            switch self {
            case .indoor:
                return "\(availableTableCount)张桌子，每桌\(seatsPerTable)个座位"
            case .outdoor:
                return "\(availableTableCount)张桌子，每桌\(seatsPerTable)个座位"
            }
        }
        
        var englishDescription: String {
            switch self {
            case .indoor:
                return "\(availableTableCount) tables, \(seatsPerTable) seats per table"
            case .outdoor:
                return "\(availableTableCount) tables, \(seatsPerTable) seats per table"
            }
        }
    }
    
    // MARK: - 预订数据模型
    
    /// 预订信息
    struct ReservationInfo {
        let partySize: Int
        let seatingType: SeatingType
        let reservationTime: Date
        let specialRequests: String?
        
        /// 验证预订信息是否有效
        var isValid: Bool {
            return partySize >= minimumPartySize &&
                   partySize <= maximumPartySize &&
                   reservationTime > Date()
        }
    }
    
    // MARK: - 座位可用性检查
    struct SeatAvailability {
        /// 检查指定时间段的座位可用性
        /// - Parameters:
        ///   - seatingType: 座位类型（室内/室外）
        ///   - date: 预订日期
        ///   - time: 预订时间
        ///   - partySize: 用餐人数
        ///   - dataManager: 数据管理器
        /// - Returns: 可用座位数量
        static func getAvailableSeats(for seatingType: SeatingType, at date: Date, time: Date, partySize: Int, dataManager: DataManager) -> Int {
            let totalSeats = seatingType == .indoor ? IndoorSeating.totalSeats : OutdoorSeating.totalSeats
            
            // 从DataManager获取真实的预订数据
            let bookedSeats = getBookedSeats(for: seatingType, at: date, time: time, dataManager: dataManager)
            
            return max(0, totalSeats - bookedSeats)
        }
        
        /// 获取指定时间段已预订的座位数
        /// 基于40分钟翻台时间计算座位占用情况
        private static func getBookedSeats(for seatingType: SeatingType, at date: Date, time: Date, dataManager: DataManager) -> Int {
            let calendar = Calendar.current
            let turnoverMinutes = BusinessLogic.turnoverTime
            
            // 获取所有预订订单
            let reservationOrders = dataManager.orders.filter { order in
                // 只考虑预订订单且为堂食
                return order.isReservation && 
                       order.diningType == .dineIn &&
                       order.reservationSeatingType == seatingType &&
                       order.status != .cancelled
            }
            
            var bookedSeats = 0
            
            // 检查每个预订是否与当前时间段冲突
            for order in reservationOrders {
                guard let reservationTime = order.reservationTime,
                      let partySize = order.reservationPartySize else {
                    continue
                }
                
                // 检查预订日期是否匹配
                if !calendar.isDate(reservationTime, inSameDayAs: date) {
                    continue
                }
                
                // 计算预订时间段的开始和结束时间
                let reservationStart = reservationTime
                let reservationEnd = calendar.date(byAdding: .minute, value: turnoverMinutes, to: reservationStart) ?? reservationStart
                
                // 检查当前查询时间是否与预订时间段重叠
                let queryEnd = calendar.date(byAdding: .minute, value: turnoverMinutes, to: time) ?? time
                
                // 如果时间段重叠，则计入已预订座位
                if time < reservationEnd && queryEnd > reservationStart {
                    bookedSeats += partySize
                }
            }
            
            // 确保不超过总座位数
            let totalSeats = seatingType == .indoor ? IndoorSeating.totalSeats : OutdoorSeating.totalSeats
            return min(bookedSeats, totalSeats)
        }
        
        /// 检查指定时间是否有足够座位
        /// - Parameters:
        ///   - seatingType: 座位类型
        ///   - date: 预订日期
        ///   - time: 预订时间
        ///   - partySize: 用餐人数
        ///   - dataManager: 数据管理器
        /// - Returns: 是否有足够座位
        static func hasAvailableSeats(for seatingType: SeatingType, at date: Date, time: Date, partySize: Int, dataManager: DataManager) -> Bool {
            let availableSeats = getAvailableSeats(for: seatingType, at: date, time: time, partySize: partySize, dataManager: dataManager)
            return availableSeats >= partySize
        }
        
        /// 获取下一个可用时间段建议
        /// - Parameters:
        ///   - seatingType: 座位类型
        ///   - date: 预订日期
        ///   - requestedTime: 用户请求的时间
        ///   - partySize: 用餐人数
        ///   - dataManager: 数据管理器
        /// - Returns: 建议的时间，如果没有可用时间则返回nil
        static func getNextAvailableTime(for seatingType: SeatingType, at date: Date, after requestedTime: Date, partySize: Int, dataManager: DataManager) -> Date? {
            let calendar = Calendar.current
            var currentTime = requestedTime
            
            // 检查接下来的时间段（每40分钟检查一次，最多检查6小时）
            for _ in 0..<9 { // 6小时 / 40分钟 = 9次检查
                currentTime = calendar.date(byAdding: .minute, value: BusinessLogic.turnoverTime, to: currentTime) ?? currentTime
                
                // 检查是否在营业时间内
                let hour = calendar.component(.hour, from: currentTime)
                if hour >= 21 { // 超过营业时间
                    break
                }
                
                if hasAvailableSeats(for: seatingType, at: date, time: currentTime, partySize: partySize, dataManager: dataManager) {
                    return currentTime
                }
            }
            
            return nil
        }
    }
    
    // MARK: - 时间生成
    
    /// 生成可预订时间列表
    static func generateAvailableReservationTimes() -> [Date] {
        var availableTimes: [Date] = []
        let calendar = Calendar.current
        let now = Date()
        
        // 获取接下来7天的可预订时间
        for dayOffset in 0..<7 {
            guard let targetDate = calendar.date(byAdding: .day, value: dayOffset, to: now) else { continue }
            
            // 获取当天的营业时间
            let businessHours = BusinessHoursManager.getBusinessHours(for: targetDate)
            
            guard let startTime = businessHours.startTime,
                  let endTime = businessHours.endTime else { continue }
            
            // 生成当天的时间段
            var currentTime = startTime
            while currentTime < endTime {
                // 如果是今天，确保时间在当前时间之后
                if calendar.isDate(targetDate, inSameDayAs: now) {
                    if currentTime > now {
                        availableTimes.append(currentTime)
                    }
                } else {
                    availableTimes.append(currentTime)
                }
                
                // 增加时间间隔
                guard let nextTime = calendar.date(byAdding: .minute, value: timeIntervalMinutes, to: currentTime) else { break }
                currentTime = nextTime
            }
        }
        
        return availableTimes
    }
    
    // MARK: - 本地化文本
    
    /// 本地化文本
    struct Localization {
        
        // MARK: - 标题
        static let reservationTitle_zh = "预订信息"
        static let reservationTitle_en = "Reservation Details"
        
        static let partySizeTitle_zh = "用餐人数"
        static let partySizeTitle_en = "Party Size"
        
        static let seatingTypeTitle_zh = "座位类型"
        static let seatingTypeTitle_en = "Seating Type"
        
        static let timeSelectionTitle_zh = "预订时间"
        static let timeSelectionTitle_en = "Reservation Time"
        
        static let specialRequestsTitle_zh = "特殊要求"
        static let specialRequestsTitle_en = "Special Requests"
        
        // MARK: - 按钮
        static let confirmReservation_zh = "确认预订"
        static let confirmReservation_en = "Confirm Reservation"
        
        static let cancel_zh = "取消"
        static let cancel_en = "Cancel"
        
        static let next_zh = "下一步"
        static let next_en = "Next"
        
        static let previous_zh = "上一步"
        static let previous_en = "Previous"
        
        // MARK: - 占位符
        static let specialRequestsPlaceholder_zh = "请输入特殊要求（可选）"
        static let specialRequestsPlaceholder_en = "Enter special requests (optional)"
        
        // MARK: - 免责声明
        static let disclaimerTitle_zh = "预订须知"
        static let disclaimerTitle_en = "Reservation Terms"
        
        // MARK: - 预订条款配置
        static let reservationTerms_zh = [
            "所有预订须全额付款方可确认成功。",
            "请您准时到达，餐厅将为您保留桌位10分钟。",
            "若您迟到超过20分钟，餐厅有权取消您的预订，并保留不予退款的权利。",
            "如需修改或取消预订，请至少提前2小时联系餐厅，我们将尽力为您协调安排。"
        ]
        
        static let reservationTerms_en = [
            "All reservations require full payment for confirmation.",
            "Please arrive on time. The restaurant will hold your table for 10 minutes.",
            "If you are more than 20 minutes late, the restaurant reserves the right to cancel your reservation and retain the payment.",
            "To modify or cancel your reservation, please contact the restaurant at least 2 hours in advance, and we will do our best to accommodate your request."
        ]
        
        // MARK: - 扫码入座配置
        static let qrScanPrompt_zh = "请扫码桌上二维码"
        static let qrScanPrompt_en = "Please scan the QR code on your table"
        
        // MARK: - 服务类型分组配置
        static let immediateServiceGroup_zh = "立即服务"
        static let immediateServiceGroup_en = "Immediate Service"
        
        static let reservationServiceGroup_zh = "预定"
        static let reservationServiceGroup_en = "Reservation"
        
        // MARK: - 时间日期选择配置
        static let timeDateSelection_zh = "时间/日期"
        static let timeDateSelection_en = "Time/Date"
        
        // MARK: - 验证消息
        static let invalidPartySize_zh = "请选择有效的用餐人数（1-20人）"
        static let invalidPartySize_en = "Please select a valid party size (1-20 people)"
        
        static let invalidTime_zh = "请选择有效的预订时间"
        static let invalidTime_en = "Please select a valid reservation time"
        
        static let noAvailableSeats_zh = "所选时间段暂无可用座位"
        static let noAvailableSeats_en = "No available seats for the selected time"
        
        // MARK: - 成功消息
        static let reservationSuccess_zh = "预订成功！"
        static let reservationSuccess_en = "Reservation confirmed!"
        
        // MARK: - 辅助方法
        static func getLocalizedText(chinese: String, english: String, language: String) -> String {
            return language == "zh" ? chinese : english
        }
    }
}

// MARK: - 扩展：BusinessHoursManager
extension BusinessHoursManager {
    
    /// 获取指定日期的营业时间
    static func getBusinessHours(for date: Date) -> (startTime: Date?, endTime: Date?) {
        let calendar = Calendar.current
        let weekday = calendar.component(.weekday, from: date)
        
        // 获取营业时间（这里使用现有的营业时间逻辑）
        let startHour: Int
        let endHour: Int
        
        // 周一到周五：11:00-19:00
        // 周六周日：11:00-20:00
        if weekday >= 2 && weekday <= 6 { // 周一到周五
            startHour = 11
            endHour = 19
        } else { // 周六周日
            startHour = 11
            endHour = 20
        }
        
        let startTime = calendar.date(bySettingHour: startHour, minute: 0, second: 0, of: date)
        let endTime = calendar.date(bySettingHour: endHour, minute: 0, second: 0, of: date)
        
        return (startTime, endTime)
    }
}